package com.drawu.drawuspring.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.drawu.drawuspring.domain.DTO.GamePageDto;
import com.drawu.drawuspring.domain.DTO.PageDTO;
import com.drawu.drawuspring.domain.Result;
import com.drawu.drawuspring.domain.VO.GameCommentsVo;
import com.drawu.drawuspring.domain.VO.GameInfoVo;
import com.drawu.drawuspring.domain.VO.UserVO;
import com.drawu.drawuspring.domain.po.*;
import com.drawu.drawuspring.enums.AppHttpCodeEnum;
import com.drawu.drawuspring.mapper.ActivitiesMapper;
import com.drawu.drawuspring.mapper.GameInfoMapper;
import com.drawu.drawuspring.service.IGameCommentsService;
import com.drawu.drawuspring.service.IGameHaveService;
import com.drawu.drawuspring.service.IGameInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.drawu.drawuspring.service.IUsersService;
import com.drawu.drawuspring.utils.AppThreadLocalUtil;
import com.drawu.drawuspring.utils.BeanUtils;
import com.drawu.drawuspring.utils.CollUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author hui
 * @since 2024-11-26
 */
@Service
@RequiredArgsConstructor
public class GameInfoServiceImpl extends ServiceImpl<GameInfoMapper, GameInfo> implements IGameInfoService {

    private final IGameCommentsService gameCommentsService;
    private final IUsersService usersService;
    private final IGameHaveService gameHaveService;

    @Override
    public Result addGameInfo(GameInfo gameInfo) {
        if (gameInfo == null) {
            return Result.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        boolean save = this.save(gameInfo);
        if (!save) {
            return Result.errorResult(AppHttpCodeEnum.SERVER_ERROR);
        }
        return Result.success();
    }

    @Override
    public Result deleteGameInfo(Integer id) {
        if (id == null) {
            return Result.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        boolean remove = this.removeById(id);
        if (!remove) {
            return Result.errorResult(AppHttpCodeEnum.SERVER_ERROR);
        }
        return Result.success();
    }

    @Override
    public Result updateGameInfo(GameInfo gameInfo) {
        if (gameInfo == null) {
            return Result.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        boolean update = this.updateById(gameInfo);
        if (!update) {
            return Result.errorResult(AppHttpCodeEnum.SERVER_ERROR);
        }
        return Result.success();
    }

    @Override
    public Result addComment(GameComments comment) {
        if (comment.getGameId() == null&&comment.getComment() == null) {
            return Result.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        boolean save = this.gameCommentsService.save(comment);
        if (!save) {
            return Result.errorResult(AppHttpCodeEnum.SERVER_ERROR);
        }
        return Result.success();
    }

    @Override
    public Result getGameInfo(GamePageDto gamePageDto) {
        Page<GameInfo> page = lambdaQuery()
                .like(gamePageDto.getKeywords() != null, GameInfo::getName, gamePageDto.getKeywords())
                .like(gamePageDto.getKeywords() != null, GameInfo::getBrief, gamePageDto.getKeywords())
                .like(gamePageDto.getKeywords() != null, GameInfo::getGameOver, gamePageDto.getKeywords())
                .like(gamePageDto.getKeywords() != null, GameInfo::getGameConfiguration, gamePageDto.getKeywords())
                .like(gamePageDto.getKeywords() != null, GameInfo::getGameFlow, gamePageDto.getKeywords())
                .like(gamePageDto.getKeywords() != null, GameInfo::getTypes, gamePageDto.getKeywords())
                .page(gamePageDto.toMpPageDefaultSortByCreateTimeDesc());
        List<GameInfo> records = page.getRecords();
        List<GameInfoVo> gameInfoVos = BeanUtils.copyList(records, GameInfoVo.class);
        if (CollUtils.isEmpty(records)) {
            return Result.success(PageDTO.of(page));
        }
        Users user = AppThreadLocalUtil.getUser();
        if (user == null || user.getId()== null) {
            return Result.success(PageDTO.of(page, gameInfoVos));
        }
        List<GameHave> gameHaveList = gameHaveService.lambdaQuery().eq(GameHave::getUserId, user.getId()).list();
        Set<Integer> gameIdSet = gameHaveList.stream().map(GameHave::getGameId).collect(Collectors.toSet());
//        Set<Integer> gameIds = records.stream().map(GameInfo::getId).filter(Objects::nonNull).collect(Collectors.toSet());
//        List<GameComments> comments = gameCommentsService.listByGameIds(gameIds);
//        Map<Integer, List<GameComments>> commentsMap = comments.stream().collect(Collectors.groupingBy(GameComments::getGameId));
        for(GameInfoVo gameInfoVo : gameInfoVos){
            if(gameIdSet.contains(gameInfoVo.getId())){
                gameInfoVo.setHaveGame(true);
            }
        }
        return Result.success(PageDTO.of(page, gameInfoVos));
    }

    @Override
    public Result getGameInfoById(Integer id) {
        if (id == null) {
            return Result.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        GameInfo gameInfo = this.getById(id);
        if (gameInfo == null) {
            return Result.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        GameInfoVo gameInfoVo = BeanUtils.copyProperties(gameInfo, GameInfoVo.class);
        return Result.success(gameInfoVo);
    }

    @Override
    public Result addUserGame(Integer gameId) {
        Integer userId = AppThreadLocalUtil.getUser().getId();
        if (gameId == null|| userId == null) {
            return Result.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        GameHave gameHave = new GameHave();
        gameHave.setGameId(gameId);
        gameHave.setUserId(userId);
        gameHaveService.save(gameHave);
        return Result.success();
    }

    @Override
    public Result getUserGame() {
        Users user = AppThreadLocalUtil.getUser();
        if (user.getId() == null) {
            return Result.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        List<GameHave> gameHaveList = gameHaveService.lambdaQuery().eq(GameHave::getUserId, user.getId()).groupBy(GameHave::getCreateTime).list();
        return Result.success(gameHaveList);
    }
}
